package exp;

import java.util.ArrayList;
import java.util.TreeMap;

import tools.FileReaderEnhance;
import tools.FileWriterEnhance;

/**
 * Sort all tweets according to time and find peaks of tweets
 * 
 * @author Lanjun
 *
 */
public class EXP2 {
	public static double mean = 0;
	public static double variance = 0;
	private static final double ALPHA = 0.125;
	private static final double T = 2;
	private static final int P = 5;
	private static final int interval = 120;
	
	public static void main(String[] args) {
		String filename = "data/plaintext1/9_11_memorial_2011";
		String[] lines = FileReaderEnhance.readToString(filename, "UTF-8")
				.split("\n");
		
		TreeMap<Long, ArrayList<String>> sorted = new TreeMap<>();
		
		for (String line : lines) {
//			System.out.println(line);
			String [] elements = line.split("\t~\t");
			Long time = Long.parseLong(elements[1]);
			String tweet = elements[0];
			if (sorted.containsKey(time)) {
				ArrayList<String> tweets = sorted.get(time);
				tweets.add(tweet);
				sorted.put(time, tweets);
			} else {
				ArrayList<String> tweets = new ArrayList<>();
				tweets.add(tweet);
				sorted.put(time, tweets);
			}
		}
		
		outputFile(sorted);
		
		// split according to minutes
		long start = sorted.firstKey();
		long end = sorted.lastKey();
		long minutes = (end - start)/interval + 1;
		ArrayList<TimeRangeTweets> tweetsInMinutes = new ArrayList<>();
		for (int i = 0; i < minutes; i++) {
			TimeRangeTweets tr =new TimeRangeTweets();
			tr.start = start + i*interval;
			tr.end = start + (i+1)*interval;
			tweetsInMinutes.add(tr);
		}
		
		for (Long key : sorted.keySet()) {
			int position = (int) ((key - start)/interval);
			TimeRangeTweets tr = tweetsInMinutes.get(position);
			for (String tweet : sorted.get(key)) {
				tr.timesLong.add(key);
				tr.tweets.add(tweet);
			}
		}
		
		outputFrequency(tweetsInMinutes);
		
		//init the mean
		mean = tweetsInMinutes.get(0).getSize();
		//init the variance, use the value of p
		double temp = 0.0;
		for (int i = 0; i < P; i++) {
			TimeRangeTweets a = tweetsInMinutes.get(i);
			double c = a.timesLong.size();
			temp += (c-mean) * (c-mean);
		}
		variance = temp / minutes;
		
		//algorithm begin
		for (int i = 1; i < minutes; i++) {
			TimeRangeTweets a = tweetsInMinutes.get(i);
			TimeRangeTweets a_1 = tweetsInMinutes.get(i-1);
			if ((Math.abs(a.getSize() - mean) / variance > T) && (a.getSize() > a_1.getSize())) {
				int startPF = i - 1;
				while ((i < minutes) && (a.getSize() > a_1.getSize())) {
					update(a.getSize());
					i++;
					a = tweetsInMinutes.get(i);
					a_1 = tweetsInMinutes.get(i-1);
				}
				int endPF = i;
				while ((i < minutes) && (a.getSize() > tweetsInMinutes.get(startPF).getSize())) {
					if ((Math.abs(a.getSize() - mean) / variance > T) && (a.getSize() > a_1.getSize())) {
						endPF = --i;
						break;
					} else {
						update(a.getSize());
						endPF = i++;
						a = tweetsInMinutes.get(i);
						a_1 = tweetsInMinutes.get(i-1);
					}
				}
				System.out.println((startPF + 1) + "\t" + (endPF + 1));
			} else {
				update(a.getSize());
			}
		}		
	}

	private static void outputFrequency(ArrayList<TimeRangeTweets> tweetsInMinutes) {
		StringBuilder sb = new StringBuilder();
		for (TimeRangeTweets key : tweetsInMinutes) {
			sb.append(key.start);
			sb.append("\t");
			sb.append(key.getSize());
			sb.append('\n');
		}
		
		FileWriterEnhance fw = new FileWriterEnhance("data/plaintext1_sorted/9_11_memorial_2011_freq", "UTF-8");
		fw.WriteToFile(sb.toString());
	}

	private static void update(int updatevalue) {
		double diff = Math.abs(mean - updatevalue);
		variance = ALPHA*diff + (1-ALPHA)*variance;
		mean = ALPHA*updatevalue + (1-ALPHA)*mean;
	}

	/**
	 * output all sorted tweets in to a file
	 * @param sorted
	 */
	private static void outputFile(TreeMap<Long, ArrayList<String>> sorted) {
		StringBuilder sb = new StringBuilder();
		for (Long key : sorted.keySet()) {
			sb.append(key);
			sb.append("\t~\t");
			sb.append(sorted.get(key));
			sb.append('\n');
		}
		
		FileWriterEnhance fw = new FileWriterEnhance("data/plaintext1_sorted/9_11_memorial_2011", "UTF-8");
		fw.WriteToFile(sb.toString());
	}
}
